package com.lxw.search.service;

import com.alibaba.fastjson.JSON;
import com.lxw.framework.domain.course.CoursePub;
import com.lxw.framework.domain.course.TeachplanMediaPub;
import com.lxw.framework.domain.search.CourseSearchParam;
import com.lxw.framework.model.response.CommonCode;
import com.lxw.framework.model.response.QueryResponseResult;
import com.lxw.framework.model.response.QueryResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.RequestBuilder;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class CourseSearchService {
    @Autowired
    private RestHighLevelClient  client;

    @Autowired
    private RestClient restClient;

    @Value("${yh.elasticsearch.index}")
    private String index;

    @Value("${yh.elasticsearch.type}")
    private String type;
    @Value("${yh.elasticsearch.source_field}")
    private String source_field; //伪静态化 *.html
    @Value("${yh.elasticsearch.mediaIndex}")
    private String mediaIndex;

    public QueryResponseResult searchCourse(Integer page, Integer size, CourseSearchParam courseSearchParam) {
        SearchRequest request = new SearchRequest(index);
        request.types(type);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        String[] fields = source_field.split(",");
        //设置搜索结果字段
        searchSourceBuilder.fetchSource(fields,new String[]{});

        if (courseSearchParam == null){
            courseSearchParam = new CourseSearchParam();
        }
        //创建BoolQueryBuilder对象
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if(StringUtils.isNotEmpty(courseSearchParam.getKeyword())){
            MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders
                    .multiMatchQuery(courseSearchParam.getKeyword(), "name",
                            "description", "teachplan");
            multiMatchQueryBuilder.minimumShouldMatch("50%").field("name",10);
            boolQueryBuilder.must(multiMatchQueryBuilder);
        }
        //判断一级分类不为空,则过滤
        if(StringUtils.isNotEmpty(courseSearchParam.getMt())){
            boolQueryBuilder.filter(QueryBuilders.termQuery("mt",courseSearchParam.getMt()));
        }
        //判断二级分类不为空,则过滤
        if(StringUtils.isNotEmpty(courseSearchParam.getSt())){
            boolQueryBuilder.filter(QueryBuilders.termQuery("st",courseSearchParam.getSt()));
        }
        //判断难度等级不为空,则过滤
        if(StringUtils.isNotEmpty(courseSearchParam.getGrade())){
            boolQueryBuilder.filter(QueryBuilders.termQuery("grade",courseSearchParam.getGrade()));
        }

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font class='eslight'>");
        highlightBuilder.postTags("</font>");
        highlightBuilder.fields().add(new HighlightBuilder.Field("name"));

        //把highlightBuilder设置到searchSourceBuilder
        searchSourceBuilder.highlighter(highlightBuilder);
        //把boolQueryBuilder设置到searchSourceBuilder
        searchSourceBuilder.query(boolQueryBuilder);


        //把searchSourceBuilder设置到searchRequest
        request.source(searchSourceBuilder);
        if (page<=0){
            page = 1;
        }
        if (size<=0){
            size = 10;
        }
        searchSourceBuilder.from((page-1)*size);
        searchSourceBuilder.size(size);

        QueryResult<CoursePub> queryResult = new QueryResult<>();

        //执行搜索
        try {
            SearchResponse response = client.search(request);
            SearchHits searchHits = response.getHits();
            long totalHits = searchHits.getTotalHits();
            queryResult.setTotal(totalHits);
            SearchHit[] hits = searchHits.getHits();
            List<CoursePub> pubs = new ArrayList<>();
            for (SearchHit hit:hits) {
//                CoursePub coursePub = new CoursePub();
//                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                String sourceAsString = hit.getSourceAsString();
                CoursePub coursePub = JSON.parseObject(sourceAsString, CoursePub.class);
                pubs.add(coursePub);
                //处理高亮结果集
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                if (highlightFields != null){
                    HighlightField highlightField = highlightFields.get("name");
                    if ((highlightField !=null)){
                        Text[] texts = highlightField.getFragments();
                        StringBuffer stringBuffer = new StringBuffer();
                        for (Text text : texts) {
                            stringBuffer.append(text);
                        }
                        coursePub.setName(stringBuffer.toString());
                    }
                }
            }
            queryResult.setList(pubs);
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return new QueryResponseResult(CommonCode.FAIL,null);
        }

        QueryResponseResult result = new QueryResponseResult(CommonCode.SUCCESS,queryResult);
        return result;
    }

    public Map<String, CoursePub> getAllCourseById(String courseId) {
        SearchRequest request = new SearchRequest(index);
        request.types(type);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termQuery("id", courseId));
        request.source(searchSourceBuilder);
        Map<String, CoursePub> map = new HashMap<>();
        try {
            SearchResponse search = client.search(request);
            SearchHits hits = search.getHits();
            long totalHits = hits.getTotalHits();
            SearchHit[] searchHits = hits.getHits();
            for (SearchHit hit:searchHits) {
                String sourceAsString = hit.getSourceAsString();
                CoursePub coursePub = JSON.parseObject(sourceAsString, CoursePub.class);
                map.put(courseId,coursePub);
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return map;
    }

    public TeachplanMediaPub getmedia(String teachplanId) {
        //创建搜索请求对象
        SearchRequest searchRequest = new SearchRequest(mediaIndex);
        searchRequest.types(type);

        //
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        searchSourceBuilder.query(QueryBuilders.termQuery("teachplan_id",teachplanId));
        searchRequest.source(searchSourceBuilder);
        TeachplanMediaPub teachplanMediaPub = new TeachplanMediaPub();
        try {
            SearchResponse searchResponse = client.search(searchRequest);
            SearchHits hits = searchResponse.getHits();
            SearchHit[] searchHits = hits.getHits();
            for (SearchHit hit:searchHits) {
                String sourceAsString = hit.getSourceAsString();
                teachplanMediaPub = JSON.parseObject(sourceAsString, TeachplanMediaPub.class);
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return teachplanMediaPub;
    }
}
